package com.cloud.pole.common.util.security;

import java.io.ByteArrayOutputStream;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import org.apache.commons.codec.binary.Base64;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.Cipher;

import org.springframework.util.Base64Utils;

public class RSAUtils {
	
	/**
	 * 加密算法RSA
	 */
	public static final String KEY_ALGORITHM = "RSA";

	/**
	 * RSA最大解密密文大小
	 */
	private static final int MAX_DECRYPT_BLOCK = 128;
	
	/**
	 * RSA最大加密明文大小
	 */
	 private static final int MAX_ENCRYPT_BLOCK = 117;
	 
	 private static final String PUBLIC_KEY = "RSAPublicKey";


	 private static final String PRIVATE_KEY = "RSAPrivateKey";
	 
	 /**
	  * 签名算法
	  */
	 public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
	 
	 public static final String DATA_ENCODING = "UTF-8";
	/**
	 * 生成公钥和私钥
	 * @return 
	 * @throws Exception
	 */
	public static Map<String, Object> getKeys() throws Exception {
	    KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
	    keyPairGen.initialize(1024);
	    KeyPair keyPair = keyPairGen.generateKeyPair();
	    RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
	    RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
	    Map<String, Object> keyMap = new HashMap<String, Object>(2);
	    keyMap.put(PUBLIC_KEY, publicKey);
	    keyMap.put(PRIVATE_KEY, privateKey);
	    return keyMap;
	}
	/**
	* <p>
	* 获取私钥
	* </p>
	* 
	* @param keyMap
	*            密钥对
	* @return
	* @throws Exception
	*/
	public static String getPrivateKey(Map<String, Object> keyMap) throws Exception {
	Key key = (Key) keyMap.get(PRIVATE_KEY);
	return Base64.encodeBase64String(key.getEncoded());
	}


	/**
	* <p>
	* 获取公钥
	* </p>
	* 
	* @param keyMap
	*            密钥对
	* @return
	* @throws Exception
	*/
	public static String getPublicKey(Map<String, Object> keyMap) throws Exception {
	Key key = (Key) keyMap.get(PUBLIC_KEY);
	return Base64.encodeBase64String(key.getEncoded());
	}
	public static String getPrivateKeyStr(PrivateKey privateKey)
	        throws Exception {
	    return new String(Base64Utils.encode(privateKey.getEncoded()));
	}

	public static String getPublicKeyStr(PublicKey publicKey) throws Exception {
	    return new String(Base64Utils.encode(publicKey.getEncoded()));
	}
	/**
	 * 使用私钥解密
	 * @param encryptContent
	 * @return
	 */
	public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey){
		PKCS8EncodedKeySpec pkcs8KeySpec = null;
		byte[] keyBytes = null;
		KeyFactory keyFactory = null;
		Key privateK = null;
		Cipher cipher = null;
		ByteArrayOutputStream out = null;
		byte[] decryptedData = null;
		try{
	         keyBytes = Base64Utils.decodeFromString(privateKey);
	         pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
	         keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
	         privateK = keyFactory.generatePrivate(pkcs8KeySpec);
	         cipher = Cipher.getInstance(keyFactory.getAlgorithm());
	         cipher.init(Cipher.DECRYPT_MODE, privateK);
	         int inputLen = encryptedData.length;
	         out = new ByteArrayOutputStream();
	         int offSet = 0;
	         byte[] cache;
	         int i = 0;
	         // 对数据分段解密
	         while (inputLen - offSet > 0) {
	             if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
	                 cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
	             } else {
	                 cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
	             }
	             out.write(cache, 0, cache.length);
	             i++;
	             offSet = i * MAX_DECRYPT_BLOCK;
	         }
	         decryptedData = out.toByteArray();
	         out.close();
		}
		catch(Exception ex){
			ex.printStackTrace();
		}		
		return decryptedData;
	}
	
	/**
	 * 使用私钥解密
	 * @param encryptContent
	 * @return
	 */
	public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey){
		byte[] keyBytes = null;
		Key publicK = null;
		Cipher cipher = null;
		ByteArrayOutputStream out = null;
		X509EncodedKeySpec x509KeySpec = null;
		KeyFactory keyFactory = null;
		byte[] decryptedData = null;
		try{
			 keyBytes = Base64Utils.decodeFromString(publicKey);
	         x509KeySpec = new X509EncodedKeySpec(keyBytes);
	         keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
	         publicK = keyFactory.generatePublic(x509KeySpec);
	         cipher = Cipher.getInstance(keyFactory.getAlgorithm());
	         cipher.init(Cipher.DECRYPT_MODE, publicK);
	         int inputLen = encryptedData.length;
	         out = new ByteArrayOutputStream();
	         int offSet = 0;
	         byte[] cache;
	         int i = 0;
	         // 对数据分段解密
	         while (inputLen - offSet > 0) {
	             if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
	                 cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
	             } else {
	                 cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
	             }
	             out.write(cache, 0, cache.length);
	             i++;
	             offSet = i * MAX_DECRYPT_BLOCK;
	         }
	         decryptedData = out.toByteArray();
	         out.close();
		}
		catch(Exception ex){
			ex.printStackTrace();
		}		
		return decryptedData;
	}
	
	/**
	 * 使用私钥加密
	 * @param content
	 * @param privateKey
	 * @return
	 */
	public static byte[] encryptByPrivateKey(byte[] data, String privateKey){
		String encryptContent = null;
		byte[] keyBytes  = null;
		PKCS8EncodedKeySpec pkcs8KeySpec = null;
		KeyFactory keyFactory = null;
		Key privateK = null;
		Cipher cipher = null;
		int inputLen = 0;
		ByteArrayOutputStream out = null;
		byte[] encryptedData = null;
		try{
		    keyBytes = Base64Utils.decode(privateKey.getBytes());
		    pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
		    keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
		    privateK = keyFactory.generatePrivate(pkcs8KeySpec);
		    cipher = Cipher.getInstance(keyFactory.getAlgorithm());
			cipher.init(Cipher.ENCRYPT_MODE, privateK);
			inputLen = data.length;
		    out = new ByteArrayOutputStream();
			int offSet = 0;
			byte[] cache;
			int i = 0;
			// 对数据分段加密
			while (inputLen - offSet > 0) {
				if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
					cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
				} else {
					cache = cipher.doFinal(data, offSet, inputLen - offSet);
				}
				out.write(cache, 0, cache.length);
				i++;
				offSet = i * MAX_ENCRYPT_BLOCK;
			}
			encryptedData = out.toByteArray();
			out.close();
		}
		catch(Exception ex){
			ex.printStackTrace();
		}		
		return encryptedData;
	}
	/**
	 * 使用公钥加密
	 * @param content
	 * @param publicKey
	 * @return
	 */
	public static byte[] encryptByPublicKey(byte[] data, String publicKey){
		byte[] keyBytes  = null;
		KeyFactory keyFactory = null;
		Key publicK = null;
		Cipher cipher = null;
		int inputLen = 0;
		ByteArrayOutputStream out = null;
		X509EncodedKeySpec x509KeySpec = null;
		byte[] encryptedData = null;
		try{
			keyBytes = Base64Utils.decode(publicKey.getBytes());
			x509KeySpec = new X509EncodedKeySpec(keyBytes);
			keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
			publicK = keyFactory.generatePublic(x509KeySpec);
			// 对数据加密
			cipher = Cipher.getInstance(keyFactory.getAlgorithm());
			cipher.init(Cipher.ENCRYPT_MODE, publicK);
			inputLen = data.length;
			out = new ByteArrayOutputStream();
			int offSet = 0;
			byte[] cache;
			int i = 0;
			// 对数据分段加密
			while (inputLen - offSet > 0) {
				if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
					cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
				} else {
					cache = cipher.doFinal(data, offSet, inputLen - offSet);
				}
				out.write(cache, 0, cache.length);
				i++;
				offSet = i * MAX_ENCRYPT_BLOCK;
			}
			encryptedData = out.toByteArray();
			out.close();
		}
		catch(Exception ex){
			ex.printStackTrace();
		}		
		return encryptedData;
	}
	
    /**
     * 用私钥对信息生成数字签名
     * @param data 已加密数据
     * @param privateKey 私钥(BASE64编码)
     * @return
     * @throws Exception
     */
    public static String sign(byte[] data, String privateKey){
    	byte[] keyBytes = null;
    	PKCS8EncodedKeySpec pkcs8KeySpec = null;
    	KeyFactory keyFactory = null;
    	PrivateKey privateK  = null;
    	Signature signature = null;
    	String signContent = null;
    	try{
    		 keyBytes = Base64Utils.decode(privateKey.getBytes());
    	     pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
    	     keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
    	     privateK = keyFactory.generatePrivate(pkcs8KeySpec);
    	     signature = Signature.getInstance(SIGNATURE_ALGORITHM);
    	     signature.initSign(privateK);
    	     signature.update(data);
    	     signContent =  Base64Utils.encodeToString(signature.sign());
    	}
		catch(Exception ex){
			ex.printStackTrace();
		}	
        return signContent;
    }

    /**
  	  * 校验数字签名
     * @param data 已加密数据
     * @param publicKey 公钥(BASE64编码)
     * @param sign 数字签名
     * @return
     * @throws Exception
     * 
     */
    public static boolean verifySign(byte[] data, String publicKey, String sign){
    	byte[] keyBytes = null;
    	X509EncodedKeySpec keySpec = null;
    	PublicKey publicK = null;
    	Signature signature = null;
    	KeyFactory keyFactory = null;
    	boolean check = false;
    	try{
    		 keyBytes = Base64Utils.decodeFromString(publicKey);
    	     keySpec = new X509EncodedKeySpec(keyBytes);
    	     keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
    	     publicK = keyFactory.generatePublic(keySpec);
    	     signature = Signature.getInstance(SIGNATURE_ALGORITHM);
    	     signature.initVerify(publicK);
    	     signature.update(data);
    	     check = signature.verify(Base64Utils.decodeFromString(sign));
    	}
		catch(Exception ex){
			ex.printStackTrace();
		}	       
        return check;
    }

    /**
     * java端公钥加密
     */
    public static String encryptedDataOnJava(String data, String publicKey) {
        try {
        	data = Base64Utils.encodeToString(encryptByPublicKey(data.getBytes(DATA_ENCODING), publicKey));
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return data;
    }

    /**
     * java端私钥解密
     */
    public static String decryptDataOnJava(String data, String privateKey) {
        String msg = "";
        try {
            byte[] rs = Base64Utils.decodeFromString(data);
             //以utf-8的方式生成字符串
            msg = new String(decryptByPrivateKey(rs, privateKey), DATA_ENCODING); 
        } catch (Exception e) {
            e.printStackTrace();
        }
        return msg;
    }


    /**
     * 将字节数组转换为十六进制表示的字符串
     * @param bstr
     * @return
     */
    public static String convertBytesToString(byte[] btSource)
    {
       int i = 0, nValue = 0;
       String strDest = "", strTmp = "";

       if (btSource == null)
          return null;
       try
       {
          for (i = 0; i < btSource.length; i++)
          {
             nValue = (int) btSource[i];
             if (nValue < 0)
                nValue = nValue + 256;
             strTmp = Integer.toHexString(nValue);

             if (strTmp.length() <= 1)
                strTmp = "0" + strTmp; //仅有一位时，前面补0

             strDest += strTmp;
          }
       }
       catch (Exception e)
       {
          strDest = null;
       }
       return strDest;
    }

    /**
     * 将十六进制字字符串转换为字节数组
     * @param srcBuff
     * @return byte[]
     */
    public static byte[] convertStringToBytes(String srcBuff)
    {
       byte tmp = 0;
       int i = 0, j = 0;
       String subBuff = "";
       byte[] btResult = null;

       if (srcBuff == null)
          return null;
       try
       {
          btResult = new byte[srcBuff.length() / 2];
          for (i = 0, j = 0; i < srcBuff.length(); i += 2, j++)
          {
             subBuff = srcBuff.substring(i, i + 2);
             tmp = (byte) Integer.parseInt(subBuff, 16);
             btResult[j] = tmp;
          }
       }
       catch (Exception e)
       {
          btResult = null;
       }
       return btResult;
    }
   
	 /*
	  * 测试自己封装java端加密和解密的方法,公钥加密、私钥解密
	  */
	public static void testJavaRsa() {
		String PUBLICKEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDTJgBBJTXHnnUcaFCRcjThQCiTLKrsZw+6jtp2utfr1M0yufIh/Es+rp/izR+JRgp2Nxx5gWeqyX0/V7P8fbrvI6PTGYV4EKGjJXE+gFs/SNpEk4OuiY7coJBY6te9V87sULF//+mwc2UnuCHBcQsTPp+FF+kbHWGEDWdFzQFQnQIDAQAB";
		String PRIVATEKEY = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBANMmAEElNceedRxoUJFyNOFAKJMsquxnD7qO2na61+vUzTK58iH8Sz6un+LNH4lGCnY3HHmBZ6rJfT9Xs/x9uu8jo9MZhXgQoaMlcT6AWz9I2kSTg66JjtygkFjq171XzuxQsX//6bBzZSe4IcFxCxM+n4UX6RsdYYQNZ0XNAVCdAgMBAAECgYA1xa226XUCuzXz4BT0lXMmEiLDKFL3FWAKEKtOJVMruevwCS7CvO+krPAG4FoxqWasqGhWAUCXW+zLntg1aweZvLCcFL3BJKPs20nUyvUtKJdycOr+vqIEdv325VqgowvJ7SA015l/R+TYB1gZhJGD2wk20Mlx9OYfl/PHjlFJwQJBAO8iop+eJZ/NXnffE9FlVpmWj+YvknhnnCvwkH22T/lJwkwlT4xh9OjQUgihiR/HXuhfAQu7tUxk9ts4SclpwnkCQQDiChbXEoRgfhqpmmMORk/LM7UKIqH6YReEUv/+LdIl+dBlZJ3Jix/No7baK7EFee9Z4txtmokHQMUOyrVstZZFAkEAkjakJmJk8NN6CmMcU/DZRWl4rK6zqOj45Sjev+6j8XF22mYJwHT4cQ1Gyz4xgHu/fObx1cG8tWwaP6mn+/2tSQJBAIi656QDfHXN8hzj2cV5vKzDQ2C1IFwPPSV6+4TqfLMiEPA0U8nlUUCYJnSEd1lDsAgkVYgrMXZktI7FCcePdC0CQHoVCqrlYtBPsonNTJ3kexGUd8vsm3nVkn+KevIamPxuz1rHi28wolulYcUxT382sRC2hrztwj/lh8LdRFUKolc=";
		String data = "24234234sfsfsf滴答滴答滴答滴答滴答滴答";
		data = encryptedDataOnJava(data, PUBLICKEY);
		System.out.println("加密数据：" + data);
		System.out.println("解密数据：" + decryptDataOnJava(data, PRIVATEKEY));
	}

	public static void testFrontEncrptAndAfterDecrypt() {
		String PRIVATEKEY = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAIn2zWqU7K/2qm5pOpq5bp9R+3MTnStWTfJU9nC/Vo7UKH9dITPvrELCTK+qlqpx5Fes+l0GY7n6u4n4jyiw4ejsvkZYQ5ww477yLOn2FcoEGuZEwPgSCmfTST0OFUgQqn+/J11k9L92jEHyieE3qmhMkMt0UsVUSJwx/nZxo30ZAgMBAAECgYBD3YHigeuEC4R+14iaf8jo2j0kuGtB3Cxvnlez0otTqw1YyYkBsU49cLKkXvfKVEgM0Ow/QltgKvSBxCE31PrrDka5TygVMqqA/IM7NrDvjUcGLjyoeNmLA8660fWcDxUTlAGN5kxIvUATayVwKVflpWPWu0FPKsWrZustnEo+4QJBAMCmYsWqAKWYMVRXFP3/XGRfio8DV793TOckyBSN9eh8UhgoZyT3u7oeHmDJEwm4aNMHlg1Pcdc6tNsvi1FRCiUCQQC3VNzfF4xOtUgX7vWPL8YVljLuXmy12iVYmg6ofu9l31nwM9FLQ1TRFglvF5LWrIXTQb07PgGd5DJMAQWGsqLlAkAPE7Z9M73TN+L8b8hDzJ1leZi1cpSGdoa9PEKwYR/SrxAZtefEm+LEQSEtf+8OfrEtetWCeyo0pvKKiOEFXytFAkEAgynL/DC0yXsZYUYtmYvshHU5ayFTVagFICbYZeSrEo+BoUDxdI9vl0fU6A5NmBlGhaZ65G+waG5jLc1tTrlvoQJAXBEoPcBNAosiZHQfYBwHqU6mJ9/ZacJh3MtJzGGebfEwJgtln5b154iANqNWXpySBLvkK+Boq7FYRiD83pqmUg==";
		String data = "FBGU7sQfpSfCgB2hqFuIqkivEUHVRHD8JFdyxYeWqQHsTj9UEuVmvi28n1fOHRwW+3aZD3ttdzfUHWiXD2NErcX/CYs5BtSXT7RcJfWWcXvegq5BBDEAJCADWCRdYnblN+SLUC+ctDXcLw4xmjwAajowSzhCfY/lU3TdnJjO488=";
		System.out.println("解密数据：" + decryptDataOnJava(data, PRIVATEKEY));
	}
	
	/**
	 * 私钥加密——公钥解密
	 * @throws Exception
	 */
	public static void testSign() throws Exception {
		String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDTJgBBJTXHnnUcaFCRcjThQCiTLKrsZw+6jtp2utfr1M0yufIh/Es+rp/izR+JRgp2Nxx5gWeqyX0/V7P8fbrvI6PTGYV4EKGjJXE+gFs/SNpEk4OuiY7coJBY6te9V87sULF//+mwc2UnuCHBcQsTPp+FF+kbHWGEDWdFzQFQnQIDAQAB";
		String privateKey = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBANMmAEElNceedRxoUJFyNOFAKJMsquxnD7qO2na61+vUzTK58iH8Sz6un+LNH4lGCnY3HHmBZ6rJfT9Xs/x9uu8jo9MZhXgQoaMlcT6AWz9I2kSTg66JjtygkFjq171XzuxQsX//6bBzZSe4IcFxCxM+n4UX6RsdYYQNZ0XNAVCdAgMBAAECgYA1xa226XUCuzXz4BT0lXMmEiLDKFL3FWAKEKtOJVMruevwCS7CvO+krPAG4FoxqWasqGhWAUCXW+zLntg1aweZvLCcFL3BJKPs20nUyvUtKJdycOr+vqIEdv325VqgowvJ7SA015l/R+TYB1gZhJGD2wk20Mlx9OYfl/PHjlFJwQJBAO8iop+eJZ/NXnffE9FlVpmWj+YvknhnnCvwkH22T/lJwkwlT4xh9OjQUgihiR/HXuhfAQu7tUxk9ts4SclpwnkCQQDiChbXEoRgfhqpmmMORk/LM7UKIqH6YReEUv/+LdIl+dBlZJ3Jix/No7baK7EFee9Z4txtmokHQMUOyrVstZZFAkEAkjakJmJk8NN6CmMcU/DZRWl4rK6zqOj45Sjev+6j8XF22mYJwHT4cQ1Gyz4xgHu/fObx1cG8tWwaP6mn+/2tSQJBAIi656QDfHXN8hzj2cV5vKzDQ2C1IFwPPSV6+4TqfLMiEPA0U8nlUUCYJnSEd1lDsAgkVYgrMXZktI7FCcePdC0CQHoVCqrlYtBPsonNTJ3kexGUd8vsm3nVkn+KevIamPxuz1rHi28wolulYcUxT382sRC2hrztwj/lh8LdRFUKolc=";
        System.err.println("私钥加密——公钥解密");
        String source = "0001530672084391";
        System.out.println("原文字：\r\n" + source);
        byte[] data = source.getBytes();
        byte[] encodedData = encryptByPrivateKey(data, privateKey);
        System.out.println("加密后：\r\n" + AESUtils.parseByte2HexStr((encodedData)) + "\n");
        byte[] decodedData = decryptByPublicKey(encodedData, publicKey);
        String target = new String(decodedData);
        System.out.println("解密后: \r\n" + target);
        System.err.println("私钥签名——公钥验证签名");
        String sign = sign(encodedData, privateKey);
        System.err.println("签名:\r" + sign);
        boolean status = verifySign(encodedData, publicKey, sign);
        System.err.println("验证结果:\r" + status);
        
        publicKey = "30819c300d06092a864886f70d010101050003818a00308186028180778f79be0e88f7d0a54c969982e0c4be0be121506d3e383421e1421a950c94410438ff92d6c035bbaab31af430a3c48b607a96e8cda49c10fcf1724dc66996981621f618e81bf7c3693657e25a719ee7de1441ab6c70bdd848593d07bde4361f6951bab7111ed1f76a9a5c46f99b4786052e892ea95b7093b7e30a07dced4f53020111";
        publicKey = Base64Utils.encodeToString(convertStringToBytes(publicKey));
        
        System.err.println("publicKey:\r" + publicKey);

		String strSign="44c6e0d5a2de7cf30a4a58dbbe462f7c4883c922489913ce38db5c774e77f5d6dff83aef1e732cdf90a53fde9b3e5880a8625e7cfd259523118033321ac40a2ce6e7b84ba6b0634fca6c9ad690695e493b032c398f3114507a63c8759b4e83e96447d4621ab699daf97a55083ab36f188b1e4736c37265158ca627988bd940dc";
        strSign = Base64Utils.encodeToString(convertStringToBytes(strSign));
        System.err.println("strSign:\r" + strSign);

		String strSrc="POSID=042114723&BRANCHID=430000000&ORDERID=20052716264403015911&PAYMENT=1.00&CURCODE=01&REMARK1=&REMARK2=&ACC_TYPE=12&SUCCESS=Y&TYPE=1&REFERER=http://klz-t.royao.net/index.php/wap/do-payment.html&CLIENTIP=118.249.22.95&ACCDATE=20200527";
		 
        encodedData = strSrc.getBytes();
        status = verifySign(encodedData, publicKey, strSign);
        System.err.println("验证结果:\r" + status);
        
        
    }
	
	/**
	 * 公钥加密——私钥解密
	 * @throws Exception
	 */
	public static void test() throws Exception {
		System.err.println("公钥加密——私钥解密");

	  	String privateKey = "MIIBhQIBADANBgkqhkiG9w0BAQEFAASCAW8wggFrAgEAAkwArZB09ZnrnuXSQHhYLyRlMtML5P8W63PzhUnl13KlOs/2Ipzhx4qUXyckvRSBX+772uU4H6hD9gIxhCUcKfib9UP4tTAZDsTi02xDAgMBAAECS0ut0VHF65c9Xo/96XWkyPuASo9vKu8/f89+iVmIA8PBKfGttkTgB5f9jZ+L69OpdAy9pJnbIr3JKUcqTT7zp9qIt5Z2luWywU06AQImDdAjGDKBO7O6D3cvMI40aSmWYJ/OBYVbv3ibsUXqt3Kx5EnGRcsCJgyQtGpYUNT5g0gV0NCaOl70Ty8feAbAk7vM7xGIXtdrV1gUCORpAiYGlnWmXK/14Umjhpwi9C9a2FK30n9XcrrHHqZibY3739+nmOfO8QImAmie3R/u5tSp0OC1tbdK5zboEv1yUcEK0N5ZGcBNhfgCt1Sn27kCJgnpEN5eEMl3vp7pK8USs7Yu2r1KYHYx+drkztrPJOc2kEp8fPhV";
    	String publicKey = "MGcwDQYJKoZIhvcNAQEBBQADVgAwUwJMAIDUceSl69vYAOOQzP6rAcZaIUiKRcO6oTbTYEG1CBkLDjM9cfNaO1Rx13omjx1rHz6NOWfEI+wsh/tniFUN7Pn+T60gly7Sg6LAxQIDAQAB";
    	
	/*	String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOXJ0qTuse0F1LU8wiojKUkwkYOBlZ9XskMXLamudos6rIi5vOzHEHsg/IbjSQ0PRZ2T2HdaykqHFwVZWVNIHgX+oBKYtfzweOwPPcjpbzlK91FXLp9JMKa1iKYrazlABiiGpJ8x27U+LAnnup9NnnTRv5UYzcskS8tUziIk3TsQIDAQAB";
		String privateKey = "MIICXQIBAAKBgQDOXJ0qTuse0F1LU8wiojKUkwkYOBlZ9XskMXLamudos6rIi5vOzHEHsg/IbjSQ0PRZ2T2HdaykqHFwVZWVNIHgX+oBKYtfzweOwPPcjpbzlK91FXLp9JMKa1iKYrazlABiiGpJ8x27U+LAnnup9NnnTRv5UYzcskS8tUziIk3TsQIDAQABAoGAaJikyMcLgajXQNEOjRdtT8VfPLlikChO7D9sGcWeOYGntNKefKk/OUlVmp/RYP2ofMoR19EbWrJOHUQj92aP1QNi3Q3wbrAR8AEKH8dkIAfba9EyY4NL31SvXNfPrnuxM48Xuq7qH0/jtZeCDq3j69Ep8LmSF+0z5ubd/dzXx0kCQQDuIaah8/Ba8Z3U04gwUjToIpaMC+HtK/nVS8MeXande/vPKEHKxHHihGMK+Y0oaZ3OpoRFwopqj/h7tOcegeiXAkEA3diwOLm5pjxhoezvaicn2s9VhdsWmNESpbBo8ZrhpKPhjNuM5GqAd+Vf+Kc58hLG06pjL47wDm53KvWkRxAm9wJBAMuKRdSuHiaN2Rs9x22OBpzYW5fO3EiNyxjOjjOZWYTv4bcasMmxCarU/5c04LvHMtScrfi2pPsangiXAumnnncCQQC9X6POSHx5s0GEgEU/UH1tA1/2C7eWa6KHXbe3xoanjF2VaDU1JtTThDIQiG+mfPDM7r4Mcu/o4dNIELhTES6xAkAS+MS6+qHwGfJ9P2jUbpwn38YcEYQTIVwkAAoMXnPjLgU98m1JQqJRjJv2/eDZnBiQu8XKsMG1GQcL9+DeYtVj";
	*/	String source = "682863";
        System.out.println("\r加密前文字：\r\n" + source);
        byte[] data = source.getBytes();
        byte[] encodedData = encryptByPublicKey(data, publicKey);
        
        String encodedDataStr = Base64Utils.encodeToString(encodedData);
        System.out.println("加密后文字：\r\n" + encodedDataStr);
        
//        encodedDataStr = "Vv+AYPW5Jx5DhyS0OAnUtKNHpSCYh6ozMV0joR3cnESK4GGvMLqpHznk9gcaxcpO8aW7lrhTDdta/oS4BjIYJUoj4hc+FmQJ2eIyOgcTb3YbCKuj26CyvRC8jiy27jtxiwCA/C6/k2Vk4Viz/IR2b+xbhrwG/W2BSwTWWAuD56U=";
//        
//        byte[] decodedData = decryptByPrivateKey(Base64Utils.decodeFromString(encodedDataStr), privateKey);
//        String target = new String(decodedData);
//        System.out.println("解密后文字: \r\n" + target);
        
        publicKey = "30819c300d06092a864886f70d010101050003818a00308186028180778f79be0e88f7d0a54c969982e0c4be0be121506d3e383421e1421a950c94410438ff92d6c035bbaab31af430a3c48b607a96e8cda49c10fcf1724dc66996981621f618e81bf7c3693657e25a719ee7de1441ab6c70bdd848593d07bde4361f6951bab7111ed1f76a9a5c46f99b4786052e892ea95b7093b7e30a07dced4f53020111";
        source = "POSID=042114723&BRANCHID=430000000&ORDERID=20052716264403015911&PAYMENT=1.00&CURCODE=01&REMARK1=&REMARK2=&ACC_TYPE=12&SUCCESS=Y&TYPE=1&REFERER=http://klz-t.royao.net/index.php/wap/do-payment.html&CLIENTIP=118.249.22.95&ACCDATE=20200527";

        
        
    }
	
	/**
	 * 公钥加密随机串
	 * @param data
	 * @param publicKey
	 * @return
	 */
	public static String encryptByPublicKey(String data,String publicKey){
		byte[] dataNoteStr = data.getBytes();
		byte[] encodedDataNoteStr = encryptByPublicKey(dataNoteStr, publicKey);
		String encodedNoteStr = AESUtils.parseByte2HexStr(encodedDataNoteStr);
		return encodedNoteStr;
	}
	
	/**
	 * 私钥解密随机串
	 * @param data
	 * @param publicKey
	 * @return
	 */
	public static String decryptByPrivateKey(String data,String privateKey){
		byte[] decodedDataNoteStr = AESUtils.parseHexStr2Byte(data);
        byte[] decodedData = RSAUtils.decryptByPrivateKey(decodedDataNoteStr, privateKey);
        String decodedNoteStr = new String(decodedData);
		return decodedNoteStr;
	}
	
	public static void main(String[] args){
		try {
			Map<String, Object> map = RSAUtils.getKeys();
			String privateKey = getPrivateKey(map);
			String publicKey = getPublicKey(map);
			System.out.println(privateKey);
			System.out.println(publicKey);
			String strSrc="POSID=042114723&BRANCHID=430000000&ORDERID=20052716264403015911&PAYMENT=1.00&CURCODE=01&REMARK1=&REMARK2=&ACC_TYPE=12&SUCCESS=Y&TYPE=1&REFERER=http://klz-t.royao.net/index.php/wap/do-payment.html&CLIENTIP=118.249.22.95&ACCDATE=20200527";
			String strSign = sign(strSrc.getBytes(), privateKey);
			System.out.println(strSign);
			
			boolean status = verifySign(strSrc.getBytes(), publicKey, strSign);
		    System.err.println("验证结果:\r" + status);
			//RSAUtils.getKeys();
//			RSAUtils.testSign();
//			RSAUtils.testJavaRsa();
//			RSAUtils.test();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
